<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
	<title>监控单个节点 | Elasticsearch: 权威指南 | Elastic</title>
    <!-- Give IE8 a fighting chance -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
	<link rel="stylesheet" type="text/css" href="../static/styles.css" />
</head>
<body>
<div class="main-container">
    <section id="content">
        
        <div class="content-wrapper">
            <section id="guide" lang="zh_cn">
                <div class="container">
                    <div class="row">
                        <div class="col-xs-12 col-sm-8 col-md-8 guide-section">
                            <div style="color:gray; word-break: break-all; font-size:12px;">原文地址: <a href="https://www.elastic.co/guide/cn/elasticsearch/guide/current/_monitoring_individual_nodes.html" rel="nofollow">https://www.elastic.co/guide/cn/elasticsearch/guide/current/_monitoring_individual_nodes.html</a>, 版权归 www.elastic.co 所有<br/>
                            英文版地址: <a href="https://www.elastic.co/guide/en/elasticsearch/guide/current/_monitoring_individual_nodes.html" rel="nofollow">https://www.elastic.co/guide/en/elasticsearch/guide/current/_monitoring_individual_nodes.html</a>
                            </div>
                        <!-- start body -->
                  <div class="page_header">
<b>请注意:</b><br>本书基于 Elasticsearch 2.x 版本，有些内容可能已经过时。
</div>
<div id="content">
<div class="breadcrumbs">
<span class="breadcrumb-link"><a href="index.html">Elasticsearch: 权威指南</a></span>
»
<span class="breadcrumb-link"><a href="administration.html">管理、监控和部署</a></span>
»
<span class="breadcrumb-link"><a href="cluster-admin.html">监控</a></span>
»
<span class="breadcrumb-node">监控单个节点</span>
</div>
<div class="navheader">
<span class="prev">
<a href="_cluster_health.html">« 集群健康</a>
</span>
<span class="next">
<a href="_cluster_stats.html">集群统计 »</a>
</span>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h2 class="title">
<a id="_monitoring_individual_nodes"></a>监控单个节点<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/500_Cluster_Admin/30_node_stats.asciidoc">edit</a>
</h2>
</div></div></div>
<p><code class="literal">cluster-health</code> 是对集群的所有信息的高度概述。而 <code class="literal">node-stats</code> API 则相反，它提供一个让人眼花缭乱的数组，其中包含了集群中每一个节点的统计信息。</p>

<p><code class="literal">node-stats</code> 提供的统计值如此之多，在完全熟悉它之前，你可能都搞不清楚哪些指标是最值得关注的。我们将会高亮那些最重要的监控指标（但是我们鼓励你记录接口提供的所有指标 —— 或者用 Marvel —— 因为你永远不知道何时需要这个还是那个状态）。</p>

<p><code class="literal">node-stats</code> API 可以通过如下命令执行：</p>
<div class="pre_wrapper lang-bash">
<pre class="programlisting prettyprint lang-bash">GET _nodes/stats</pre>
</div>
<p>在输出内容的开头，我们可以看到集群名称和我们的第一个节点：</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">{
   "cluster_name": "elasticsearch_zach",
   "nodes": {
      "UNr6ZMf5Qk-YCPA_L18BOQ": {
         "timestamp": 1408474151742,
         "name": "Zach",
         "transport_address": "inet[zacharys-air/192.168.1.131:9300]",
         "host": "zacharys-air",
         "ip": [
            "inet[zacharys-air/192.168.1.131:9300]",
            "NONE"
         ],
...</pre>
</div>
<p>节点排列在一个哈希对象里，以节点的 UUID 作为键名。还显示了节点网络属性的一些信息（比如传输层地址和主机名）。这些值对调试诸如节点未加入集群这类自动发现问题很有用。通常你会发现是端口用错了，或者节点绑定在错误的 IP 地址/网络接口上了。</p>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_索引部分"></a>索引部分<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/500_Cluster_Admin/30_node_stats.asciidoc">edit</a>
</h3>
</div></div></div>
<p><code class="literal">索引(indices)</code> 部分列出了这个节点上所有索引的汇总信息：</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">    "indices": {
        "docs": {
           "count": 6163666,
           "deleted": 0
        },
        "store": {
           "size_in_bytes": 2301398179,
           "throttle_time_in_millis": 122850
        },</pre>
</div>
<p>返回的信息被归入以下部分：</p>
<div class="ulist itemizedlist">
<ul class="itemizedlist">
<li class="listitem">
<code class="literal">docs</code> 展示节点内有多少文档，以及还没有从段(segment)里彻底清除的标记为已删除的文档的数量。
</li>
<li class="listitem">
<code class="literal">store</code> 部分显示节点耗用了多少物理存储空间。这个指标包括主分片和副本分片在内。如果限流时间(<code class="literal">throttle_time_in_millis</code>)很大，那可能表明你的磁盘限流设置得过低（在<a class="xref" href="indexing-performance.html#segments-and-merging" title="段和合并">段与合并</a>里讨论过）。
</li>
</ul>
</div>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">        "indexing": {
           "index_total": 803441,
           "index_time_in_millis": 367654,
           "index_current": 99,
           "delete_total": 0,
           "delete_time_in_millis": 0,
           "delete_current": 0
        },
        "get": {
           "total": 6,
           "time_in_millis": 2,
           "exists_total": 5,
           "exists_time_in_millis": 2,
           "missing_total": 1,
           "missing_time_in_millis": 0,
           "current": 0
        },
        "search": {
           "open_contexts": 0,
           "query_total": 123,
           "query_time_in_millis": 531,
           "query_current": 0,
           "fetch_total": 3,
           "fetch_time_in_millis": 55,
           "fetch_current": 0
        },
        "merges": {
           "current": 0,
           "current_docs": 0,
           "current_size_in_bytes": 0,
           "total": 1128,
           "total_time_in_millis": 21338523,
           "total_docs": 7241313,
           "total_size_in_bytes": 5724869463
        },</pre>
</div>
<div class="ulist itemizedlist">
<ul class="itemizedlist">
<li class="listitem">
<p><code class="literal">indexing</code> 显示已经索引的文档的数量。这个值是一个累加计数器。在文档被删除的时候，数值不会下降。还要注意的是，在发生内部 <em>索引</em> 操作的时候，这个值也会增加，比如说文档更新。</p>

<p>还列出了索引操作耗费的时间，正在索引的文档数量，以及删除操作的类似的统计信息。</p>
</li>
<li class="listitem">
<code class="literal">get</code> 显示通过 ID 获取文档的统计信息。包括对单个文档的 <code class="literal">GET</code> 和 <code class="literal">HEAD</code> 请求。
</li>
<li class="listitem">
<p><code class="literal">search</code> 描述 活跃中的搜索（ <code class="literal">open_contexts</code> ）的数量、查询的总次数、以及自节点启动以来在查询上消耗的总时间。
可以用 <code class="literal">query_time_in_millis / query_total</code> 的比值来粗略的评价你的查询有多高效。比值越大，每个查询花费的时间越多，你应该要考虑调优了。</p>

<p>fetch 统计信息详细列举了查询处理的后一半流程（query-then-fetch 里的 <em>fetch</em> ）。如果 fetch 耗时比 query 还多，说明磁盘较慢，或者获取了太多文档，或者可能搜索请求设置了太大的分页（比如， <code class="literal">size: 10000</code> ）。</p>
</li>
<li class="listitem">
<p><code class="literal">merges</code> 包括了 Lucene 段合并相关的信息。它会告诉你目前在运行几个合并，合并涉及的文档数量，正在合并的段的总大小，以及在合并操作上消耗的总时间。</p>

<p>如果集群写入压力很大，合并统计信息就非常重要。合并要消耗大量的磁盘 I/O 和 CPU 资源。如果你的索引有大量的写入，同时又发现大量的合并数，一定要去阅读<a class="xref" href="indexing-performance.html" title="索引性能技巧">索引性能技巧</a>。</p>

<p>注意：文档更新和删除也会导致大量的合并数，因为它们会产生最终需要被合并的段 <em>碎片</em> 。</p>
</li>
</ul>
</div>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">        "filter_cache": {
           "memory_size_in_bytes": 48,
           "evictions": 0
        },
        "fielddata": {
           "memory_size_in_bytes": 0,
           "evictions": 0
        },
        "segments": {
           "count": 319,
           "memory_in_bytes": 65812120
        },
        ...</pre>
</div>
<div class="ulist itemizedlist">
<ul class="itemizedlist">
<li class="listitem">
<p><code class="literal">filter_cache</code> 展示了已缓存的过滤器位集合所用的内存数量，以及过滤器被淘汰出内存的次数。过多的淘汰数 <em>可能</em> 说明你需要增加过滤器缓存的大小，或者你的过滤器不太适合缓存（比如它们因为基数高而在大量产生，就像是缓存一个 <code class="literal">now</code> 时间表达式）。
例如，由于基数较高，比如缓存<code class="literal">now</code>的日期表达式<span style="color:#666;">(每秒中都会产生大量的数据)</span>，它们产生了很大的波动。
</p>

<p>不过，淘汰数是一个很难评定的指标。过滤器是在每个段上缓存的，而从一个小的段里淘汰过滤器，代价比从一个大的段里要小的多。有可能你有很大的淘汰数，但是它们都发生在小段上，这对查询性能的影响很小。</p>

<p>把淘汰数指标作为一个粗略的参考。如果你看到数字很大，检查一下你的过滤器，确保他们都是正常缓存的。不断淘汰着的过滤器，哪怕都发生在很小的段上，效率也比正常缓存了的过滤器低很多。</p>
</li>
<li class="listitem">
<code class="literal">field_data</code> 显示 fielddata 使用的内存，用以聚合、排序等等。这里也有一个淘汰数。和 <code class="literal">filter_cache</code> 不同的是，这里的淘汰数是很有用的：这个数应该或者至少是接近于 0。因为 fielddata 不是缓存，任何淘汰都消耗巨大，应该避免掉。如果你在这里看到淘汰数，你需要重新评估你的内存状况、fielddata 限制、查询语句，或者三者都要。
</li>
<li class="listitem">
<p><code class="literal">segments</code> 会展示这个节点目前正在服务中的 Lucene 段的数量。这是一个重要的数字。大多数索引应该有大约 50–150 个段，哪怕它们存有 TB 级别的数十亿条文档。段数量过大表明合并出现了问题（比如，合并速度跟不上段的创建）。注意这个统计值是节点上所有索引的总数据，记住这点。</p>

<p><code class="literal">memory</code> 统计值展示了 Lucene 段自己用掉的内存大小。这里包括底层数据结构，比如倒排表、字典、布隆过滤器等。太大的段数量会增加这些数据结构带来的开销，这个内存使用量就是一个方便用来衡量开销的度量值。</p>
</li>
</ul>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_操作系统和进程部分"></a>操作系统和进程部分 (OS and Process Sections)<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/500_Cluster_Admin/30_node_stats.asciidoc">edit</a>
</h3>
</div></div></div>
<p><code class="literal">OS</code> 和 <code class="literal">Process</code> 部分基本是自描述的，不会在细节中展开讲解。它们列出了基础的资源统计值，比如 CPU 和负载。<code class="literal">OS</code> 部分描述了整个操作系统，而 <code class="literal">Process</code> 部分只显示 Elasticsearch 的 JVM 进程使用的资源情况。</p>

<p>这些都是非常有用的度量值，但通常在监视堆栈的其他地方进行度量。统计值包括下面这些：</p>
<div class="ulist itemizedlist">
<ul class="itemizedlist">
<li class="listitem">
CPU
</li>
<li class="listitem">
负载 (load)
</li>
<li class="listitem">
内存使用率 (memory usage)
</li>
<li class="listitem">
Swap 使用率
</li>
<li class="listitem">
打开的文件描述符 (open file descriptors)
</li>
</ul>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_jvm_部分"></a>JVM 部分<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/500_Cluster_Admin/30_node_stats.asciidoc">edit</a>
</h3>
</div></div></div>
<p><code class="literal">jvm</code> 部分包括了运行 Elasticsearch 的 JVM 进程一些很关键的信息。最重要的，它包括了垃圾回收的细节，这对你的 Elasticsearch 集群的稳定性有着重大影响。</p>
<div class="sidebar">
<a id="garbage_collector_primer"></a>
<div class="titlepage"><div><div>
<p class="title"><strong>垃圾回收入门</strong></p>
</div></div></div>
<p>在我们描述统计值之前，先上一门速成课程讲解垃圾回收以及它对 Elasticsearch 的影响是非常有用的。如果你对 JVM 的垃圾回收很熟悉，请跳过这段。</p>

<p>Java 是一门 <em>自动垃圾回收</em> 语言，也就是说程序员不用手动管理内存分配和回收。程序员只管写代码，然后 Java 虚拟机（JVM）按需分配内存，然后在稍后不再需要的时候清理这部分内存。</p>

<p>当内存分配给一个 JVM 进程，它是分配到一个大块里，这个块叫做 <em>堆(heap)</em> 。JVM 把堆分成两组，用 <em>代(generations)</em> 来表示：</p>
<div class="variablelist">
<dl class="variablelist">
<dt>
<span class="term">
新生代(或者伊甸园) (Young or Eden)
</span>
</dt>
<dd>
新实例化的对象分配的空间。新生代空间通常都非常小，一般在 100 MB–500 MB。新生代也包含两个 <em>幸存(survivor)</em> 空间。
</dd>
<dt>
<span class="term">
老生代 (Old)
</span>
</dt>
<dd>
较老的对象存储的空间。这些对象预计将长期留存并持续上很长一段时间。老生代通常比新生代大很多。Elasticsearch 节点可以给老生代用到 30 GB。
</dd>
</dl>
</div>
<p>当一个对象实例化的时候，它被放在新生代里。当新生代空间满了，就会发生一次新生代垃圾回收（GC）。依然是"存活"状态的对象就被转移到一个幸存区内，而"死掉"的对象被移除。如果一个对象在多次新生代 GC 中都幸存了，它就会被"终身"置于老生代了。</p>

<p>类似的过程在老生代里同样发生：空间满的时候，发生一次垃圾回收，死掉的对象被移除。</p>

<p>不过，天下没有免费的午餐。新生代、老生代的垃圾回收都有一个阶段会“停止时间”。在这段时间里，JVM 实际上停止了程序运行，以便跟踪对象图，收集死亡对象。在这个时间停止阶段，一切都不会发生。请求不被服务，ping 不被回应，分片不被分配。整个世界都真的停止了。</p>

<p>对于新生代，这不是什么大问题；那么小的数据意味着 GC 会很快执行完。但是老生代大很多，而这里面一个慢 GC 可能就意味着 1 秒乃至 15 秒的暂停 —— 这对服务器软件来说是不可接受的。</p>

<p>JVM 的垃圾回收采用了 <em>非常</em> 精密的算法，在减少暂停方面做得很棒。而且 Elasticsearch 非常努力的变成对 <em>垃圾回收友好</em> 的程序，比如内部智能的重用对象，重用网络缓冲，以及默认启用 <a class="xref" href="docvalues.html" title="Doc Values">Doc Values</a> 功能。但最终，GC 的频率和时长依然是你需要去观察的指标。因为它是集群不稳定的头号嫌疑人。</p>

<p>一个经常发生长 GC 的集群就会因为内存不足而处于高负载压力下。
这些长 GC 会导致节点短时间内从集群里掉线。
这种不稳定会导致分片频繁重定位，因为 Elasticsearch 会尝试保持集群均衡，保证有足够的副本在线。
这接着就导致网络流量和磁盘 I/O 的增加。而所有这些都是在你的集群努力服务于正常的索引和查询的同时发生的。</p>
<p>总而言之，长 GC 总是不好的，需要尽可能的减少。</p>

</div>
<p>因为垃圾回收对 Elasticsearch 是如此重要，你应该非常熟悉 <code class="literal">node-stats</code> API 里的这部分内容：</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">        "jvm": {
            "timestamp": 1408556438203,
            "uptime_in_millis": 14457,
            "mem": {
               "heap_used_in_bytes": 457252160,
               "heap_used_percent": 44,
               "heap_committed_in_bytes": 1038876672,
               "heap_max_in_bytes": 1038876672,
               "non_heap_used_in_bytes": 38680680,
               "non_heap_committed_in_bytes": 38993920,</pre>
</div>
<div class="ulist itemizedlist">
<ul class="itemizedlist">
<li class="listitem">
<p><code class="literal">jvm</code> 部分首先列出一些和堆(heap)内存使用有关的常见统计值。
你可以看到有多少堆(heap)被使用了，多少已提交（committed, 实际分配给进程的），以及堆(heap)被允许分配的最大值。
理想情况下，<code class="literal">heap_committed_in_bytes</code>应该等于<code class="literal">heap_max_in_bytes</code>。
如果已提交的(committed)大小更小，JVM 最终会被迫调整堆(heap)大小 —— 这是一个成本很高的过程。
如果这两个值不相等，阅读<a class="xref" href="heap-sizing.html" title="堆内存:大小和交换">堆内存:大小和交换</a>学习如何正确的配置它。</p>

<p><code class="literal">heap_used_percent</code> 指标是值得关注的一个数字。Elasticsearch 被配置为当堆(heap)达到 75% 的时候开始 GC。如果节点一直 &gt;= 75%，该节点正处于 <em>内存压力</em> 状态。这是个危险信号，不远的未来可能就有慢 GC 要出现了。</p>

<p>如果堆(heap)使用率一直 &gt;=85%，你就麻烦了。Heap 在 90–95% 之间，则面临可怕的性能风险，此时最好的情况是长达 10–30s 的 GC，最差的情况就是内存溢出（OOM）异常。</p>
</li>
</ul>
</div>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">   "pools": {
      "young": {
         "used_in_bytes": 138467752,
         "max_in_bytes": 279183360,
         "peak_used_in_bytes": 279183360,
         "peak_max_in_bytes": 279183360
      },
      "survivor": {
         "used_in_bytes": 34865152,
         "max_in_bytes": 34865152,
         "peak_used_in_bytes": 34865152,
         "peak_max_in_bytes": 34865152
      },
      "old": {
         "used_in_bytes": 283919256,
         "max_in_bytes": 724828160,
         "peak_used_in_bytes": 283919256,
         "peak_max_in_bytes": 724828160
      }
   }
},</pre>
</div>
<div class="ulist itemizedlist">
<ul class="itemizedlist">
<li class="listitem">
<code class="literal">新生代(young)</code>、<code class="literal">幸存区(survivor)</code>和<code class="literal">老生代(old)</code> 部分分别展示 GC 中每一个代的内存使用情况。这些统计值很方便观察其相对大小，但是在调试问题的时候，通常并不怎么重要。
</li>
</ul>
</div>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">"gc": {
   "collectors": {
      "young": {
         "collection_count": 13,
         "collection_time_in_millis": 923
      },
      "old": {
         "collection_count": 0,
         "collection_time_in_millis": 0
      }
   }
}</pre>
</div>
<div class="ulist itemizedlist">
<ul class="itemizedlist">
<li class="listitem">
<p><code class="literal">gc</code> 部分显示新生代和老生代的垃圾回收次数和累积时间。
大多数时候你可以忽略掉新生代的次数：这个数字通常都很大。这是完全正常的。</p>

<p>与之相反，老生代的垃圾回收次数应该很小，而且<code class="literal">collection_time_in_millis</code>也应该很小。
这些是累积值，所以很难给出一个阈值表示你要开始操心了（比如，一个跑了一整年的节点，即使很健康，也会有一个比较大的计数）。
这就是像 Marvel 这类工具很有用的一个原因。
GC 计数的 <em>时间趋势</em> 是个重要的考虑因素。</p>

<p>GC 花费的时间也很重要。
比如，在索引文档时，生成了一定数量的垃圾。
这是正常的，每时每刻都会导致 GC。
这些 GC 绝大多数时候都很快，对节点影响很小：新生代一般就花一两毫秒，老生代花几百毫秒。这些跟 10 秒级别的 GC 是很不一样的。</p>

<p>我们的最佳建议是定期收集 GC 次数和时长（或者使用 Marvel）然后观察 GC 频率。你也可以开启慢 GC 日志记录，在 <a class="xref" href="logging.html" title="日志记录">日志记录</a> 小节已经讨论过。</p>
</li>
</ul>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_线程池部分"></a>线程池部分<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/500_Cluster_Admin/30_node_stats.asciidoc">edit</a>
</h3>
</div></div></div>
<p>Elasticsearch 在内部维护了线程池。这些线程池相互协作完成任务，有必要的话相互间还会传递任务。通常来说，你不需要配置或者调优线程池，不过查看它们的统计值有时候还是有用的，可以深入了解集群的表现如何。</p>
<p>大约有十几个线程池，但他们格式相同：</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">  "index": {
     "threads": 1,
     "queue": 0,
     "active": 0,
     "rejected": 0,
     "largest": 1,
     "completed": 1
  }</pre>
</div>
<p>每个线程池会列出已配置的线程数量（ <code class="literal">threads</code> ），当前在处理任务的线程数量（ <code class="literal">active</code> ），以及在队列中等待处理的任务单元数量（ <code class="literal">queue</code> ）。</p>

<p>如果队列中任务单元数达到了极限，新的任务单元会开始被拒绝，你会在 <code class="literal">rejected</code> 统计值上看到它反映出来。这通常是你的集群在某些资源上碰到瓶颈的信号。因为队列满了意味着你的节点或集群在用最高速度运行，但依然跟不上任务的蜂拥而入。</p>

<div class="sidebar">
<div class="titlepage"><div><div>
<p class="title"><strong>批量操作的被拒绝数 (Bulk Rejections)</strong></p>
</div></div></div>
<p>如果你碰到了队列被拒，一般来说都是批量索引写入请求导致的。
通过并发导入程序发送很多 bulk 请求非常简单。越多越好，对吧？</p>

<p>事实上，每个集群都有它能处理的请求上限。一旦这个阈值被超过，队列会很快塞满，然后新的 bulk 请求就被拒绝了。
</p>

<p>这是一件 <em>好事情</em> 。队列拒绝是一种有用的反压方式。
它们让你知道你的集群已经在最大容量了，这比把数据塞进内存队列要好得多。增加队列大小并不能增加性能，它只是隐藏了问题。
当你的集群每秒钟只能处理 10,000 个文档的时候，无论队列是 100 还是 10,000,000 都没关系 —— 你的集群还是只能每秒处理 10,000 个文档。</p>

<p>队列简单的隐藏了性能问题，却带来了真实的数据丢失风险。根据定义，队列中的任何内容都是尚未处理的。
如果节点挂掉，这些请求都会永久的丢失。
此外，队列还要消耗大量内存，这也是不理想的。</p>

<p>在应用中，优雅的处理来自满载队列的反压，才是更好的选择。
当你收到拒绝 bulk 的响应的时候，你应该采取如下几步：</p>
<div class="olist orderedlist">
<ol class="orderedlist">
<li class="listitem">
暂停导入线程 3–5 秒。
</li>
<li class="listitem">
从批量操作的响应里提取出来被拒绝的操作。因为可能很多操作还是成功的。响应会告诉你哪些成功，哪些被拒绝了。
</li>
<li class="listitem">
发送一个新的批量请求，只包含这些被拒绝过的操作。
</li>
<li class="listitem">
如果依然碰到拒绝，再次从步骤 1 开始。
</li>
</ol>
</div>
<p>通过这个流程，你的代码可以很自然的适应集群的负载，并自然退出。</p>
<p>拒绝不是错误：它们只是意味着你要稍后重试。</p>
</div>
<p>有十几个线程池。大多数你可以安全地忽略，但是有一小部分还是值得关注的：</p>
<div class="variablelist">
<dl class="variablelist">
<dt>
<span class="term">
<code class="literal">indexing</code>
</span>
</dt>
<dd>
普通的索引请求的线程池
</dd>
<dt>
<span class="term">
<code class="literal">bulk</code>
</span>
</dt>
<dd>
批量请求，和单条的索引请求不同的线程池
</dd>
<dt>
<span class="term">
<code class="literal">get</code>
</span>
</dt>
<dd>
通过文档id获取文档(Get-by-ID) 操作
</dd>
<dt>
<span class="term">
<code class="literal">search</code>
</span>
</dt>
<dd>
所有的搜索和查询请求
</dd>
<dt>
<span class="term">
<code class="literal">merging</code>
</span>
</dt>
<dd>
专用于管理 Lucene 合并的线程池
</dd>
</dl>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_文件系统和网络部分"></a>文件系统和网络部分 (FS and Network Sections)<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/500_Cluster_Admin/30_node_stats.asciidoc">edit</a>
</h3>
</div></div></div>
<p>继续向下阅读 <code class="literal">node-stats</code> API，你会看到一串和你的文件系统相关的统计值：可用空间，数据目录路径，磁盘 I/O 统计值，等等。

如果你没有监控磁盘可用空间的话，可以从这里获取这些统计值。

磁盘 I/O 统计值也很方便，不过通常那些更专门的命令行工具（比如 <code class="literal">iostat</code> ）会更有用些。</p>

<p>显然，Elasticsearch 在磁盘空间满的时候很难运行 —— 所以请确保不会这样。</p>

<p>还有两个跟网络统计值相关的部分：</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">        "transport": {
            "server_open": 13,
            "rx_count": 11696,
            "rx_size_in_bytes": 1525774,
            "tx_count": 10282,
            "tx_size_in_bytes": 1440101928
         },
         "http": {
            "current_open": 4,
            "total_opened": 23
         },</pre>
</div>
<div class="ulist itemizedlist">
<ul class="itemizedlist">
<li class="listitem">
<code class="literal">transport</code> 显示与<em>传输地址(transport address)</em>相关的一些基础统计值。
包括节点间的通信（通常是 9300 端口）以及任意传输客户端或者节点客户端的连接。如果看到这里有很多连接数不要担心；Elasticsearch 在节点之间维护了大量的连接。
</li>
<li class="listitem">
<code class="literal">http</code> 显示 HTTP 端口（通常是 9200）的统计值。

如果你看到 <code class="literal">total_opened</code> 数很大而且还在一直上涨，这是一个明确信号，说明你的 HTTP 客户端里有没启用 keep-alive 长连接的。

持续的 keep-alive 长连接对性能很重要，因为连接、断开套接字是很昂贵的（而且浪费文件描述符）。请确认你的客户端都配置正确。
</li>
</ul>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_断路器"></a>断路器<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/500_Cluster_Admin/30_node_stats.asciidoc">edit</a>
</h3>
</div></div></div>
<p>终于到了最后一部分：跟 fielddata 断路器（在 <a class="xref" href="_limiting_memory_usage.html#circuit-breaker" title="断路器">断路器</a> 介绍过）相关的统计值：</p>
<div class="pre_wrapper lang-js pagebreak-before">
<pre class="programlisting prettyprint lang-js pagebreak-before">         "fielddata_breaker": {
            "maximum_size_in_bytes": 623326003,
            "maximum_size": "594.4mb",
            "estimated_size_in_bytes": 0,
            "estimated_size": "0b",
            "overhead": 1.03,
            "tripped": 0
         }</pre>
</div>
<p>这里你可以确定断路器的最大值（比如，一个请求试图请求更多内存, 到多大时会触发断路器）。

这个部分还会让你知道断路器被触发了多少次，以及当前配置的开销。

开销用来填充评估，因为有些请求比其他请求更难评估。</p>

<p>主要需要关注的是 <code class="literal">tripped</code> 指标。

如果这个数字很大或者持续上涨，这是一个信号，说明你的请求需要优化，或者你需要添加更多内存（单机上添加，或者通过添加新节点的方式）。</p>
</div>

</div>
<div class="navfooter">
<span class="prev">
<a href="_cluster_health.html">« 集群健康</a>
</span>
<span class="next">
<a href="_cluster_stats.html">集群统计 »</a>
</span>
</div>
</div>

                  <!-- end body -->
                        </div>
                        <div class="col-xs-12 col-sm-4 col-md-4" id="right_col">
                        
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </section>
</div>
<script src="../static/cn.js"></script>
</body>
</html>